﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlServerCe;
using System.Linq;
using System.Text;
using CryptoFiles.Common;

namespace CryptoFiles.Data
{
    public class CryptoDatabase : IDisposable
    {
        private SqlCeConnection _conn = new SqlCeConnection();
        private bool _disposed;


        public CryptoDatabase()
        {
            _conn.ConnectionString = Settings.ConnectionString;
        }

        public void Connect()
        {
            _conn.Open();
        }

        public void Disconnect()
        {
            Dispose();
        }


        public string GetUserKey(string login)
        {
            string queryGetUserKey = "select cryptokey from users where login = @login";

            SqlCeCommand cmd = new SqlCeCommand(queryGetUserKey, _conn);

            SqlCeParameter pLogin = new SqlCeParameter("@login", login);
            cmd.Parameters.Add(pLogin);

            using (SqlCeDataReader dr = cmd.ExecuteReader(CommandBehavior.SingleRow))
            {

                if (dr.Read())
                {
                    string key = (string) dr["cryptoKey"];
                    return key;
                }

                throw new UserNotFoundException(string.Format("Пользователь '{0}' не найден", login));
            }


        }


        public bool CheckUserCredentials(string login, string passwd)
        {
            string queryExists = "select count(*) from Users where login = @login and passwd = @passwd";

            SqlCeCommand cmd = new SqlCeCommand(queryExists, _conn);
            SqlCeParameter pLogin = new SqlCeParameter("@login", login);
            SqlCeParameter pPasswd = new SqlCeParameter("@passwd", passwd);


            cmd.Parameters.AddRange(new []{pLogin, pPasswd});

            int cnt = Convert.ToInt32(cmd.ExecuteScalar());

            return cnt > 0;
            
        }

        public void AddUser(string login, string passwd, string key)
        {
            string queryInsert = "insert into Users(login, passwd, cryptokey) values (@login, @passwd, @cryptokey)";
            string queryExists = "select count(*) from Users where login = @login";


            SqlCeTransaction tran = null;

            try
            {
                tran = _conn.BeginTransaction();

                SqlCeCommand cmd = new SqlCeCommand(queryExists, _conn, tran);
                cmd.Parameters.AddWithValue("@login", login);
                int cnt = Convert.ToInt16(cmd.ExecuteScalar());


                if (cnt > 0)
                    throw new UserRegistrationException("Пользователь с логином '" + login + "' уже существует", ErrorType.LoginExists);

                cmd.CommandText = queryInsert;
                cmd.Parameters.Clear();

                SqlCeParameter pLogin = new SqlCeParameter("@login", login);
                SqlCeParameter pPasswd = new SqlCeParameter("@passwd", passwd);
                SqlCeParameter pCryptokey = new SqlCeParameter("@cryptokey", key);

                cmd.Parameters.AddRange(new[] { pLogin, pPasswd, pCryptokey });
                cmd.ExecuteNonQuery();


                tran.Commit();

            }
            catch (Exception)
            {
                tran.Rollback();

                throw;
            }

           
        }


        


        #region Dispose pattern

        ~CryptoDatabase()  
        {
           Dispose(false);
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }


        private void Dispose(bool disposing)
        {

            if (!_disposed)
            {

                if (disposing)
                {
                    // dispose managed resources
                    _conn.Close();
                }

                //unmanaged resources...
            }
            _disposed = true;
        }

        #endregion

       
    }
}
